package foodmaterial.service.impl;

import foodmaterial.config.DataSourceContextHolder;
import foodmaterial.dao.InitDao;
import foodmaterial.dao.PermissionDao;
import foodmaterial.entity.*;
import foodmaterial.service.PermissionService;
import foodmaterial.utils.Constants;
import foodmaterial.utils.DateUtil;
import foodmaterial.utils.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger ;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class PermissionServiceImpl extends BaseService implements PermissionService {

    private final static Logger LOGGER = LoggerFactory.getLogger(PermissionServiceImpl.class) ;

    @Autowired
    private PermissionDao dao ;

    @Autowired
    private InitDao initDao ;

    private String checkUserAccount(SysUser sysUser) {
        SysUser user = dao.selectUserByAccount(sysUser.getAccount());
        if (user == null) return null ;
        if (sysUser.getId() == null)
            return sysUser.getAccount() + " 账号已经存在" ;
        else
            if (sysUser.getId().longValue() != user.getId().longValue())
                    return sysUser.getAccount() + " 账号已经存在" ;
        return null ;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addUser(SysUser sysUser) {
        String result = checkUserAccount(sysUser) ;
        if (result != null) return result ;
        sysUser.setId(nextId());
        int rows = dao.insertUser(sysUser);
        if (rows > 0) return null ;
        return "新增用户失败" ;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String modifyUser(SysUser sysUser) {
        String result = checkUserAccount(sysUser) ;
        if (result != null) return result ;
        int rows = dao.updateUser(sysUser);
        if (rows > 0) return null ;
        return "修改用户失败" ;
    }

    @Override
    public String modifyPassword(SysUser sysUser) {
        String result = PasswordService.checkPassword(sysUser.getPassword(),sysUser.getConfirmPassword());
        if (result != null) return result ;
        SysUser u = dao.selectUserById(sysUser.getId()) ;
        LOGGER.debug("{ 用户密码 } ==>" + u.getPassword() + " { 输入旧密码 } ==> " + PasswordUtil.encodePassword(sysUser.getOldPassword()));
        if (PasswordUtil.matches(sysUser.getOldPassword(),u.getPassword()) == false) return "旧密码输入不对" ;
        sysUser.setPassword(PasswordUtil.encodePassword(sysUser.getPassword())) ;
        dao.updateUser(sysUser) ;
        return null;
    }

    @Override
    public List<SysUser> queryUsers(String hasSupper,Long branchId,String name) {
        SysUser userDetails =this.getSysUser();
        if (userDetails.getAccount().equals("admin"))
            return dao.selectUsers(null,"true",branchId,name);
        else
            return dao.selectUsers(null,null,branchId,name);
    }

    @Override
    public List<SysUser> queryAdminUsers() {
        List<CompanyDatabase> list = initDao.selectCompanyDatabase() ;
        List<String> dbList = new ArrayList<>() ;
        for (CompanyDatabase cd : list) {
            dbList.add(cd.getDatabase()) ;
        }
        return dao.selectAdminUsers(dbList);
    }

    @Override
    public List<SysUser> queryUsersByUserType(String userType) {
        return dao.selectUsers(userType,null,null,null);
    }

    @Override
    public List<Map<String, Object>> choiceUsers(String userType) {
        return dao.choiceUsers(this.getSysUser().getDb(),userType);
    }

    @Override
    public SysUser queryUserByAccount(String account) {
        return dao.selectUserByAccount(account);
    }

    @Override
    public List<SysRole> queryRolesByUser(Long userId) {
        return dao.selectRolesByUser(userId);
    }

    @Override
    public List<SysPermission> queryPermissions(Long hasRole) {
        List<SysPermission> list = dao.selectPermissions();
        if (hasRole > 0) {
            List<RolePermissionRelation> list1 = dao.selectRolePermissionRelation(hasRole) ;
            for (RolePermissionRelation rp : list1) {
                for (SysPermission sp : list) {
                    if (rp.getPermissionId().longValue() == sp.getId().longValue()) {
                        sp.setChecked(true);
                        break;
                    }
                }
            }
        }
        return list;
    }

    private List<RolePermissionRelation> getRolePermissionRelations(SysRole sysRole) {
        List<RolePermissionRelation> list = new ArrayList<>() ;
        for (Long id : sysRole.getPerms()) {
            list.add(new RolePermissionRelation(nextId(),sysRole.getId(),id)) ;
        }
        return list ;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addRole(SysRole sysRole) {
        List<Long> permissionList = sysRole.getPerms() ;
        if (permissionList == null || permissionList.isEmpty()) {
            return "请给角色设置权限" ;
        }
        sysRole.setId(nextId());
        dao.insertRole(sysRole) ;
        List<RolePermissionRelation> list = getRolePermissionRelations(sysRole) ;
        dao.insertRolePermissionRelations(list) ;
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String modifyRole(SysRole sysRole) {
        List<Long> permissionList = sysRole.getPerms() ;
        if (permissionList == null || permissionList.isEmpty()) {
            return "请给角色设置权限" ;
        }
        dao.updateRole(sysRole) ;
        List<RolePermissionRelation> list = getRolePermissionRelations(sysRole) ;
        dao.deleteRolePermissionRelations(sysRole.getId()) ;
        dao.insertRolePermissionRelations(list) ;
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeRole(Long id) {
        dao.deleteRoleUserRelations(id) ;
        dao.deleteRolePermissionRelations(id);
        return dao.deleteRole(id) ;
    }

    @Override
    public List<SysRole> queryRole() {
        return dao.selectRole();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int grant(Long userId, List<String> roleList) {
        dao.deleteUserRoleRelations(userId) ;
        List<UserRoleRelation> list = new ArrayList<>() ;
        for (String id : roleList) {
            list.add(new UserRoleRelation(nextId(),userId,Long.valueOf(id))) ;
        }
        if (list.isEmpty()) return 1;//可以收回用户的全部权限
        dao.insertUserRoleRelations(list) ;
        return 1;
    }

    @Override
    public String resetPassword(SysUser user) {
        String result = PasswordService.checkPassword(user.getPassword(),user.getConfirmPassword());
        if (result != null) return result ;
        user.setPassword(PasswordUtil.encodePassword(user.getPassword()));
        int row = dao.updateUser(user);
        if (row == 0) return "密码重置不成功" ;
        return null ;
    }

    @Override
    public int modifySysParams(CompanySysParams companySysParams) {
        return dao.updateSysParams(companySysParams);
    }

    @Override
    public List<CompanySysParams> querySysParams() {
        return dao.selectSysParams();
    }

    @Override
    public CompanySysParams querySysParamsByCode(String code) {
        return dao.selectSysParamsByCode(code);
    }

    @Override
    public String getNextWeekDateRange() {
        Date date = DateUtil.plus(new Date(),7) ;
        int week = DateUtil.getWeek(date).getValue() ;
        Date begin = DateUtil.plus(date,(week - 1) * -1) ;
        Date end = DateUtil.plus(date,7 - week) ;
        StringBuilder sb = new StringBuilder() ;
        sb.append("{\"beginEatDate\":\"")
          .append(this.getDate(begin))
          .append("\",\"endEatDate\":\"")
          .append(this.getDate(end))
          .append("\"}");
        return sb.toString();
    }

    @Override
    public String getSystemWeek() {
        Date date = new Date() ;
        StringBuilder sb = new StringBuilder() ;
        sb.append("{\"week\":").append(DateUtil.getWeek(date).getValue()).append('}') ;
        return sb.toString();
    }

    @Override
    public UserDetails loadUserByUsername(String account) throws UsernameNotFoundException {
        if (account == null || "".equals(account))
            throw new UsernameNotFoundException("user account is not null") ;
        String[] temp = account.split(";");
        //0 表示公司用户登录 1 表示配送客户登录
        SysUser user = null ;

        if (temp[1].equals("0")) {
            user = dao.selectUserByAdmin(temp[0]);
        } else if (temp[1].equals("2")) {
            DataSourceContextHolder.setDBType(temp[2]);
            try {
                user = dao.selectUserByAccount(temp[0]);
            } finally {
                DataSourceContextHolder.clearDBType();
            }
        } else {
            DataSourceContextHolder.setDBType(temp[2]);
            try {
                user = dao.selectCustomerByAccount(temp[0],temp[2]);
                if (user != null) {
                    user.setDb(temp[2]);
                    user.setSelfAccountNonLocked(!user.getSelfAccountNonLocked());//判断是否停止供货的客户
                }
            } finally {
                DataSourceContextHolder.clearDBType();
            }
        }
        if (user == null)
            throw new UsernameNotFoundException("user account { " + account + " }not exist") ;
        LOGGER.debug("{ 用户登录 } ==>" + user);
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        if (temp[1].equals("0") || temp[1].equals("2")) {
            //换数据库
            DataSourceContextHolder.setDBType(user.getDb());
            try {
                List<SysPermission> list = dao.selectPermissionsByUser(user.getId());
                LOGGER.debug("{ 用户权限 } ==>" + list);
                list.forEach(permission -> {
                    if (permission != null) {
                        GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getCode());
                        grantedAuthorities.add(grantedAuthority);
                    }
                });
                if (temp[1].equals("0"))
                    grantedAuthorities.add(new SimpleGrantedAuthority("AAAA"));//显示公司登录菜单
                else
                    grantedAuthorities.add(new SimpleGrantedAuthority("CCCC"));//显示公司登录菜单
                user.setGrantedAuthorities(grantedAuthorities);
            } finally {
                DataSourceContextHolder.clearDBType();
            }
        } else {
            //这里固定配送客户的权限
            if (Constants.SELF_USER.equals(user.getUserType()) ||
                Constants.SELF_VIP_USER.equals(user.getUserType())) {
                if (user.getFoodSupplyType().equals(Constants.KITCHEN_FOOD))
                    grantedAuthorities.add(new SimpleGrantedAuthority("7005"));
                else
                    grantedAuthorities.add(new SimpleGrantedAuthority("7001"));
            }
            grantedAuthorities.add(new SimpleGrantedAuthority("7002"));//其他客户可以管理自己的订单
            grantedAuthorities.add(new SimpleGrantedAuthority("5010"));//其他客户可以管理自己的订单
            grantedAuthorities.add(new SimpleGrantedAuthority("1003"));
            grantedAuthorities.add(new SimpleGrantedAuthority("7003"));//客户可以查看供应商资质
            grantedAuthorities.add(new SimpleGrantedAuthority("7004"));//客户可以查看检测报告
            grantedAuthorities.add(new SimpleGrantedAuthority("BBBB"));//显示客户登录菜单
            user.setGrantedAuthorities(grantedAuthorities);
        }
        return user;
    }

}
